package com.codeoss.framework.view.parser;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.codeoss.framework.data.metadata.Column;
import com.codeoss.framework.data.metadata.Table;
import com.codeoss.framework.data.store.ITableStore;
import com.codeoss.framework.expression.Expression;
import com.codeoss.framework.expression.ExpressionUtil;
import com.codeoss.framework.util.StringUtils;
import com.codeoss.framework.view.component.Component;
import com.codeoss.framework.view.component.RollUpSummary;
import com.codeoss.framework.view.datasource.DataSourceConfig;
import com.codeoss.framework.view.util.DataSourceUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

@Service("rollupsummaryParser")
public class RollUpSummaryParser extends AbstractComponentParser {
	@Autowired
	private ITableStore tableStore;
	@Autowired
	private DataSourceUtil dataSourceUtil;
	protected void setAttributes(IParseContext parseContext, ObjectNode objectNode, Component component) {
		super.setAttributes(parseContext, objectNode, component);
		RollUpSummary rollUpSummary = (RollUpSummary) component;
		String labelExpression = objectNode.get("labelExpression").asText();
		JsonNode jsonNode = objectNode.get("col");
		if (jsonNode != null) {
			int col = objectNode.get("col").asInt();
			rollUpSummary.setCol(col);
		}

		jsonNode = objectNode.get("fieldcol");
		if (jsonNode != null) {
			int fieldCol = objectNode.get("fieldcol").asInt();
			rollUpSummary.setFieldCol(fieldCol);
		}
		if (!StringUtils.isEmpty(labelExpression)) {
			Expression expression = ExpressionUtil.convertLabelToExpression(labelExpression,
					Expression.EXPRESSION_TYPE_JAVASCRIPT);
			rollUpSummary.setLabelExpression(expression);
		}
		ObjectNode propertyMapNode = (ObjectNode) objectNode.get("propertyMap");
		if (propertyMapNode != null) {
			jsonNode = propertyMapNode.get("dataSource");
			if (jsonNode != null) {
				String dataSource = propertyMapNode.get("dataSource").asText();
				rollUpSummary.setDataSource(dataSource);
			}
			jsonNode = propertyMapNode.get("dataField");
			if (jsonNode != null) {
				String dataField = propertyMapNode.get("dataField").asText();
				rollUpSummary.setDataField(dataField);

				DataSourceConfig dataSourceConfig = dataSourceUtil.getDataSourceConfigById(parseContext.getPage(),
						rollUpSummary.getDataSource());
				Table table = tableStore.get(dataSourceConfig.getTableName());
				Column column = table.getColumnByColumnName(dataField);
				String requiredExpression = column.getRequiredExpression();
				if (!StringUtils.isEmpty(requiredExpression)) {
					Expression expression = ExpressionUtil.convertToExpression(requiredExpression,
							Expression.EXPRESSION_TYPE_JAVASCRIPT);
					rollUpSummary.setRequiredExpression(expression);
				}
				String readOnlyExpression = column.getReadOnlyExpression();
				if (!StringUtils.isEmpty(readOnlyExpression)) {
					Expression expression = ExpressionUtil.convertToExpression(readOnlyExpression,
							Expression.EXPRESSION_TYPE_JAVASCRIPT);
					rollUpSummary.setReadOnlyExpression(expression);
				}
				String defaultValueExpression = column.getDefaultValueExpression();
				if (!StringUtils.isEmpty(defaultValueExpression)) {
					Expression expression = ExpressionUtil.convertToExpression(defaultValueExpression,
							Expression.EXPRESSION_TYPE_JAVASCRIPT);
					rollUpSummary.setDefaultValueExpression(expression);
				}
				
				rollUpSummary.setDataType(column.getDataType());
				
				jsonNode = propertyMapNode.get("varName");
				String varName = "";
				if (jsonNode == null || StringUtils.isEmpty(jsonNode.asText())) {
					if (!StringUtils.isEmpty(rollUpSummary.getDataSource()) && !StringUtils.isEmpty(rollUpSummary.getDataField())) {
						varName = table.getTableName() + "_" + rollUpSummary.getDataField();
					}
				} else {
					varName = propertyMapNode.get("varName").asText();
				}
				rollUpSummary.setVarName(varName);
			}
			
			
			jsonNode = propertyMapNode.get("valueExpression");
			if(jsonNode!=null) {
				String valueExpression=jsonNode.asText();
				if (!StringUtils.isEmpty(valueExpression)) {
					String expressionType=Expression.EXPRESSION_TYPE_JAVASCRIPT;
					if(valueExpression.startsWith("@")) {
						expressionType=Expression.EXPRESSION_TYPE_SPRING;
					}
					Expression expression = ExpressionUtil.convertToExpression(valueExpression,
							expressionType);
					rollUpSummary.setValueExpression(expression);
				}
			}
		}
		jsonNode = objectNode.get("noLabel");
		if (jsonNode != null) {
			rollUpSummary.setNoLabel(jsonNode.asBoolean());
		}
	}

	public void afterPageParse(IParseContext parseContext, Component component) {
		RollUpSummary rollUpSummary = (RollUpSummary) component;
	
		DataSourceConfig dataSourceConfig = dataSourceUtil.getDataSourceConfigById(parseContext.getPage(),rollUpSummary.getDataSource());
		if (dataSourceConfig == null) {
			return;
		}
		Table table = tableStore.get(dataSourceConfig.getTableName());
		Column column = table.getColumnByColumnName(rollUpSummary.getDataField());

		if (column != null) {
			Expression requiredExpression = rollUpSummary.getRequiredExpression();
			if (requiredExpression != null) {
				parseExpression(parseContext, component, requiredExpression, "required", false);
			}

			Expression readonlyExpression = rollUpSummary.getReadOnlyExpression();
			if (readonlyExpression != null) {
				parseExpression(parseContext, component, readonlyExpression, "readonly", true);
			}

			Expression defaultValueExpression = rollUpSummary.getDefaultValueExpression();
			if (defaultValueExpression != null) {
				parseExpression(parseContext, component, defaultValueExpression, "defaultValue", false);
			}

			Expression visibleExpression = rollUpSummary.getVisibleExpression();
			if (visibleExpression != null) {
				parseExpression(parseContext, component, visibleExpression, "visible", true);
			}
		}
		super.afterPageParse(parseContext, component);
	}
	
	@Override
	protected Component createComponent(IParseContext parseContext, ObjectNode objectNode) {
		// TODO Auto-generated method stub
		return new RollUpSummary();
	}

}
